﻿using Autofac;
using Ewell.BizComponent.Service.IServer;
using Ewell.BizComponent.Service.Model.Dto;
using Ewell.BizComponent.Service.Model.Request;
using Ewell.BizComponent.Service.Model.Response;
using Ewell.BizComponent.Service.Server;
using Ewell.BizComponent.UI.Charge.Windows;
using Ewell.BizComponent.UI.Core.Model;
using Ewell.BizComponent.UI.Core.VievModel;
using Ewell.BizComponent.UI.Reg.Model.Request;
using Ewell.BizComponent.UI.Reg.Model.Response;
using Ewell.Interface.Common.Constant;
using Ewell.Interface.Common.Model.Common;
using Ewell.Interface.Common.Model.GateWay.Dto.Dict;
using Ewell.Interface.Common.Model.GateWay.Dto.Out;
using Ewell.Interface.Common.Model.GateWay.GateWayUriInfo;
using Ewell.Interface.Common.Utils;
using MahApps.Metro.Controls.Dialogs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace Ewell.BizComponent.UI.Reg.ViewModel
{
    public class OutRegVm:ViewModelBase
    {
        public IDialogCoordinator dialogCoordinator { get; set; } = DialogCoordinator.Instance;
        public IOutRegisterServer outRegisterServer { get; set; }=new OutRegisterServer();
        public Window mainWindow { get; set; }
        /// <summary>
        /// 有无排班
        /// </summary>
        private bool _hasSched;
        public bool hasSched
        {
            get { return _hasSched; }
            set
            {
                if (_hasSched != value)
                {
                    _hasSched = value;
                    OnPropertyChanged(nameof(hasSched));
                }
            }
        }
        /// <summary>
        /// 使用医生
        /// </summary>
        private bool _useDoct;
        public bool useDoct
        {
            get { return _useDoct; }
            set
            {
                if (_useDoct != value)
                {
                    _useDoct = value;
                    OnPropertyChanged(nameof(useDoct));
                }
            }
        }
        /// <summary>
        /// 患者信息
        /// </summary>
        private PatientVm _patient { get; set; }
        public PatientVm patient
        {
            get { return _patient; }
            set
            {
                if (_patient != value)
                {
                    _patient = value;
                    OnPropertyChanged(nameof(patient));
                }
            }
        }
        /// <summary>
        /// 排班信息
        /// </summary>
        private List<ScheduleVm> _scheduleVmList;
        public List<ScheduleVm> scheduleVmList
        {
            get
            {
                return _scheduleVmList;
            }
            set
            {
                if (_scheduleVmList != value)
                {
                    _scheduleVmList = value;
                    OnPropertyChanged(nameof(scheduleVmList));
                }
            }
        }
        /// <summary>
        /// 选中的排班信息
        /// </summary>
        private ScheduleVm _selectedSchedule;
        public ScheduleVm selectedSchedule
        {
            get
            {
                return _selectedSchedule;
            }
            set
            {
                if (_selectedSchedule != value)
                {
                    _selectedSchedule = value;
                    OnPropertyChanged(nameof(selectedSchedule));
                }
            }
        }
        /// <summary>
        /// 医保费别
        /// </summary>
        private List<PatientTypeVm> _patientTypeList;
        public List<PatientTypeVm> patientTypeList
        {
            get
            {
                return _patientTypeList;
            }
            set
            {
                if (_patientTypeList != value)
                {
                    _patientTypeList = value;
                    OnPropertyChanged(nameof(patientTypeList));
                }
            }
        }
        /// <summary>
        /// 已选择的医保费别
        /// </summary>
        private PatientTypeVm _selectedPatientType;
        public PatientTypeVm selectedPatientType
        {
            get
            {
                return _selectedPatientType;
            }
            set
            {
                if (_selectedPatientType != value)
                {
                    _selectedPatientType = value;
                    OnPropertyChanged(nameof(selectedPatientType));
                }
            }
        }

        /// <summary>
        /// 是否免费
        /// </summary>
        private bool _isFree;
        public bool isFree
        {
            get => _isFree; set
            {
                if (value != _isFree)
                {
                    _isFree = value;
                    OnPropertyChanged(nameof(isFree));
                }
            }
        }

        private Visibility _freeBtnVisib=Visibility.Visible;
        public Visibility freeBtnVisib
        {
            get => _freeBtnVisib;
            set
            {
                if(value != _freeBtnVisib)
                {
                    _freeBtnVisib = value;
                    OnPropertyChanged(nameof(freeBtnVisib));
                }
            }
        }
        /// <summary>
        /// 业务调用参数
        /// </summary>
        public OutRegisterRequestVm bizOutRegisterRequest { get; set; }
        /// <summary>
        /// 挂号预登记结果
        /// </summary>
        public OutPreRegisterResponse outPreRegisterResponse { get; set; }
        /// <summary>
        /// 收费预算参数
        /// </summary>
        public OutPreSettlementRequest outPreSettlementRequest { get; set; }
        /// <summary>
        /// 挂号结果
        /// </summary>
        public OutRegisterResponse outRegisterResponse { get; set; }


        /// <summary>
        /// 查询排班信息
        /// </summary>
        public ICommand querySched => new RelayCommand((object param) =>
        {
            List<ScheduleVm> scheduleList = new List<ScheduleVm>();
            if (this.hasSched)
            {
                List<OutScheduleDTO> outScheduleDTOs = default;
                if (useDoct)
                {
                    QueryScheduleByExampleV1Request request = new QueryScheduleByExampleV1Request()
                    {
                        scheduleDateBegin = DateTime.Today,
                        scheduleDateEnd = DateTime.Today.AddDays(1).AddSeconds(-1),
                        encResTypeCodings = new List<string>() { "1" },
                        bizSourceCoding = LoginInfo.loginUser.bizSourceCode == "14" ? "4" : LoginInfo.loginUser.bizSourceCode,
                        searchAllDayFlag = "1",
                        providerId = bizOutRegisterRequest.docId,
                        providerTypeCoding = "2"//就诊服务提供者类型代码 1科室2医生
                    };
                    ScheduleManageDubboService scheduleManageDubboService = new ScheduleManageDubboService();
                    var gateWayResult = scheduleManageDubboService.queryScheduleByExampleV1.Post<List<OutScheduleDTO>>(request);
                    if (!gateWayResult.success) throw new SpeedException("HISBIZ", gateWayResult.message);
                    outScheduleDTOs = gateWayResult.@object;
                }
                else
                {
                    QueryScheduleByExampleV1Request request = new QueryScheduleByExampleV1Request()
                    {
                        scheduleDateBegin = DateTime.Today,
                        scheduleDateEnd = DateTime.Today.AddDays(1).AddSeconds(-1),
                        encResTypeCodings = new List<string>() { "1" },
                        bizSourceCoding = LoginInfo.loginUser.bizSourceCode == "14" ? "4" : LoginInfo.loginUser.bizSourceCode,
                        searchAllDayFlag = "1",
                        providerId = bizOutRegisterRequest.deptCode,
                        providerTypeCoding = "1"//就诊服务提供者类型代码 1科室2医生
                    };
                    ScheduleManageDubboService scheduleManageDubboService = new ScheduleManageDubboService();
                    var gateWayResult = scheduleManageDubboService.queryScheduleByExampleV1.Post<List<OutScheduleDTO>>(request);
                    if (!gateWayResult.success) throw new SpeedException("HISBIZ", gateWayResult.message);
                    outScheduleDTOs = gateWayResult.@object;
                }
                if (outScheduleDTOs == null) return;
                foreach (var item in outScheduleDTOs)
                {
                    ScheduleVm schedule = new ScheduleVm();
                    schedule.encScheduleId = item.encScheduleId;
                    schedule.msId = item.msId;
                    schedule.msName = item.msName;
                    schedule.registrationTypeId = item.registrationTypeId;
                    schedule.registrationTypeName = item.registrationTypeName;
                    schedule.regCategoryId = item.regCategoryId;
                    schedule.quantity = item.quantity;
                    schedule.quantityUsed = item.quantityUsed;
                    schedule.quantityRemain = item.quantityRemain;
                    schedule.regAmount = item.regAmount;
                    schedule.noonTypeId = item.noonTypeId;
                    schedule.noonTypeCoding = item.noonTypeCoding;
                    schedule.noonTypeName = item.noonTypeName;
                    schedule.beginTime = item.beginTime;
                    schedule.endTime = item.endTime;
                    schedule.providerId = item.providerId;
                    schedule.providerTypeCoding = item.providerTypeCoding;
                    schedule.docId = item.providerTypeCoding == "2" ? item.providerId : "";
                    schedule.docCode = item.providerTypeCoding == "2" ? LoginInfo.loginUser.userId : "";
                    schedule.docName = item.providerTypeCoding == "2" ? item.providerName : "";
                    schedule.deptId = item.providerTypeCoding == "1" ? item.providerId : LoginInfo.loginUser.deptCode;
                    schedule.deptCode = item.providerTypeCoding == "1" ? LoginInfo.loginUser.deptCode : "";
                    schedule.deptName = item.providerTypeCoding == "1" ? item.providerName : LoginInfo.loginUser.deptName;
                    List<EsSlotSettingVm> esSlotList = new List<EsSlotSettingVm>();
                    if (item.esSlotSettingList != null)
                    {
                        foreach (var esSlot in item.esSlotSettingList)
                        {
                            EsSlotSettingVm esSlotSetting = new EsSlotSettingVm()
                            {
                                esSlotSettingId = esSlot.esSlotSettingId,
                                quantity = esSlot.quantity,
                                quantityPlaned = esSlot.quantityPlaned,
                                quantityRemain = esSlot.quantityRemain,
                                quantityUsed = esSlot.quantityUsed,
                                beginAtTime = esSlot.beginAtTime,
                                endAtTime = esSlot.endAtTime,
                            };
                            esSlotList.Add(esSlotSetting);
                        }
                    }
                    schedule.esSlotSettingList = esSlotList;
                    scheduleList.Add(schedule);
                }
            }
            else if (!this.hasSched)
            {
                List<QueryESResponse> queryESResponses = default;
                if (useDoct)
                {
                    QueryESRequest request = new QueryESRequest()
                    {
                        enabledFlag = "1",
                        providerId = bizOutRegisterRequest.docId,
                        providerTypeCoding = "2"//就诊服务提供者类型代码 1科室2医生
                    };
                    EncounterServiceDubboService encounterServiceDubboService = new EncounterServiceDubboService();
                    var gateWayResult = encounterServiceDubboService.queryESByExample.Post<List<QueryESResponse>>(request);
                    if (!gateWayResult.success) throw new SpeedException("HISBIZ", gateWayResult.message);
                    queryESResponses = gateWayResult.@object;
                }
                else
                {
                    QueryESRequest request = new QueryESRequest()
                    {
                        enabledFlag = "1",
                        providerId = bizOutRegisterRequest.deptId,
                        providerTypeCoding = "1"//就诊服务提供者类型代码 1科室2医生
                    };
                    EncounterServiceDubboService encounterServiceDubboService = new EncounterServiceDubboService();
                    var gateWayResult = encounterServiceDubboService.queryESByExample.Post<List<QueryESResponse>>(request);
                    if (!gateWayResult.success) throw new SpeedException("HISBIZ", gateWayResult.message);
                    queryESResponses = gateWayResult.@object;
                }

                if (queryESResponses == null) return;

                foreach (var item in queryESResponses)
                {
                    foreach (var esProvider in item.esProviderList)
                    {
                        foreach (var esXRegType in esProvider.esXRegTypeList)
                        {
                            ScheduleVm schedule = new ScheduleVm();
                            schedule.msId = item.msId;
                            schedule.msName = item.msName;
                            schedule.registrationTypeId = esXRegType.regTypeId;
                            schedule.registrationTypeName = esXRegType.regTypeName;
                            schedule.regCategoryId = esXRegType.regCategory;
                            schedule.regAmount = esXRegType.regAmount;
                            schedule.providerId = esProvider.esProviderId;
                            schedule.providerTypeCoding = esProvider.esProviderTypeCoding;
                            schedule.docId = esProvider.esProviderTypeCoding == "2" ? esProvider.esProviderId : "";
                            schedule.docCode = esProvider.esProviderTypeCoding == "2" ? LoginInfo.loginUser.userCode : "";
                            schedule.docName = esProvider.esProviderTypeCoding == "2" ? esProvider.esProviderName : "";
                            schedule.deptId = esProvider.esProviderTypeCoding == "1" ? esProvider.esProviderId : "";
                            schedule.deptCode = esProvider.esProviderTypeCoding == "1" ? LoginInfo.loginUser.deptCode : "";
                            schedule.deptName = esProvider.esProviderTypeCoding == "1" ? esProvider.esProviderName : "";
                            List<RegNoonTypeVm> regNoonTypes = new List<RegNoonTypeVm>();
                            if (esXRegType.regNoonTypeList != null)
                            {
                                foreach (var regNoonType in esXRegType.regNoonTypeList)
                                {
                                    RegNoonTypeVm regNoonTypeVm = new RegNoonTypeVm();
                                    regNoonTypeVm.regNoonTypeId = regNoonType.regNoonTypeId;
                                    regNoonTypeVm.beginAtTime = regNoonType.beginAtTime;
                                    regNoonTypeVm.endAtTime = regNoonType.endAtTime;
                                    regNoonTypes.Add(regNoonTypeVm);
                                }
                            }
                            schedule.regNoonTypeList = regNoonTypes;
                            scheduleList.Add(schedule);
                        }
                    }
                }
            }
            scheduleVmList = scheduleList.OrderBy(o => o.beginTime).ToList();
        });

        ///// <summary>
        ///// 挂号事件
        ///// </summary>
        public ICommand register => new RelayCommand(async (object param) =>
        {
            if (this.outPreRegisterResponse != null&& outPreRegisterResponse.preSettlementList!=null&& outPreRegisterResponse.preSettlementList.Count>0)
            {
                outRegisterServer.PreRegistCancel(outPreRegisterResponse.preSettlementList.Select(s => s.outEncounterId).ToList());
                this.outPreRegisterResponse = null;
            }
            //加号标志
            string encResAddFlag = "0";
            if (patient == null || string.IsNullOrWhiteSpace(patient.patientId))
            {
                await this.dialogCoordinator.ShowMessageAsync(this, "警告", "没有患者信息,请建档后重试!");
                return;
            }
            if (selectedPatientType == null)
            {
                await this.dialogCoordinator.ShowMessageAsync(this, "警告", "请选择医保费别!");
                return;
            }
            if (param == null)
            {
                await this.dialogCoordinator.ShowMessageAsync(this, "警告","未选择挂号内容！请选择挂号内容！");
                return;
            }
            ScheduleVm schedule = param as ScheduleVm;
            //参数校验
            var scheduleSlotId = schedule.esSlotSettingList?.OrderBy(o => o.endAtTime).FirstOrDefault(f => f.endAtTime >= DateTime.Now)?.esSlotSettingId;
            //schedule.encScheduleId为空是不限号
            //schedule.encScheduleId不为空是限号，限号且无排班报错
            if (hasSched && string.IsNullOrWhiteSpace(scheduleSlotId) && !string.IsNullOrWhiteSpace(schedule.encScheduleId))
            {
                ConfigQueryRequest request = new ConfigQueryRequest()
                {
                    codes = new List<string>() { "3059" }
                };
                ConfigAllDubboService configAllDubboService = new ConfigAllDubboService();
                var gateWayConfig = configAllDubboService.queryPageConfig.Post<List<ConfigResponse>>(request);
                if (!gateWayConfig.success) throw new SpeedException("HISBIZ", gateWayConfig.message);
                if (gateWayConfig.@object != null && gateWayConfig.@object.All(c => c.value.Trim() != "1"))
                {
                    MessageDialogResult dialogResult = await this.dialogCoordinator.ShowMessageAsync(this, "警告!", $"【{schedule.docName + schedule.deptName}】出诊的【{schedule.msName}】已无可用号源，是否加号");
                    if (dialogResult == MessageDialogResult.Affirmative)
                    {
                        encResAddFlag = "1";
                        scheduleSlotId = schedule.esSlotSettingList?.OrderByDescending(o => o.endAtTime).FirstOrDefault()?.esSlotSettingId;
                    }
                }
                else
                {
                    await this.dialogCoordinator.ShowMessageAsync(this, "警告", "号源没有当前时段可用的排班！");
                    return;
                }
            }
            var regNoonType = schedule.regNoonTypeList?.OrderBy(o => o.endAtTime).FirstOrDefault(f => f.endAtTime >= DateTime.Now);
            //if(!hasSched&& regNoonType == null)
            //{
            //    MessageBox.Show("出班午别列表不包含当前时段!");
            //    return;
            //}

            //挂号预算
            OutPreRegisterRequest preRegisterDto = new OutPreRegisterRequest()
            {
                bizSourceCoding = LoginInfo.loginUser.bizSourceCode,
                patient = new PatientDto()
                {
                    insurTypeId = selectedPatientType.no,
                    patientId = patient.patientId,
                    patientName = patient.name,
                },
                preRegist = new PreRegistDto()
                {
                    visitTypeCoding = "1", //1现场就诊 2线上就诊
                    outEncounterList = new List<ScheduleDto>()
                    {
                        new ScheduleDto()
                        {
                            msId=schedule.msId,
                            paymentTypeCoding=isFree?"2":"1",//1正常收费 2全免费
                            scheduleId=schedule.encScheduleId,
                            scheduleSlotId=scheduleSlotId,//排班时段标识 有排班必传
                            providerId=schedule.providerId,
                            providerTypeCoding=schedule.providerTypeCoding,
                            regTypeId=schedule.registrationTypeId,
                            regCategoryId=schedule.regCategoryId,
                            attendAtBegin=DateTime.Today,
                            attendAtEnd=DateTime.Today.AddDays(1).AddSeconds(-1),
                            encResAddFlag=encResAddFlag,
                        }
                    }
                }
            };
            
            try
            {
                //挂号预登记
                this.outPreRegisterResponse = outRegisterServer.PreRegister(preRegisterDto);
            }
            catch (SpeedException ex)
            {
                await this.dialogCoordinator.ShowMessageAsync(this, "警告" , $"预算失败!,{ex.Message}");
                return;
            }
            catch (Exception ex)
            {
                await this.dialogCoordinator.ShowMessageAsync(this, "警告" , $"预算失败!,{ex.Message}");
                return;
            }

            this.outPreSettlementRequest = new OutPreSettlementRequest()
            {
                bizSourceCoding = LoginInfo.loginUser.bizSourceCode,
                menuId = LoginInfo.menuId,
                preSettlementList = this.outPreRegisterResponse.preSettlementList,
                patient = new PatientDto()
                {
                    insurTypeId = patient.patientTypeNo,
                    patientId = patient.patientId,
                    patientName = patient.name,
                },
                encounter = new EncounterDto()
                {
                    encounterId = long.Parse(this.outPreRegisterResponse.preSettlementList.FirstOrDefault().outEncounterId),
                },
                settlementTypeCode = "1"
            };

            try
            {
                ChargeWindow chargeWindow = new ChargeWindow()
                {
                    chargeVm = new Charge.ViewModel.ChargeVm()
                    {
                        preSettlementVm = new Charge.ViewModel.PreSettlementVm()
                        {
                            outPreSettlementRequest = this.outPreSettlementRequest,
                            selectedPatientType = selectedPatientType,
                            patient= patient,
                        },
                        patientVm = patient,
                    },
                };
                chargeWindow.ShowDialog();
                outRegisterResponse = new OutRegisterResponse
                {
                    outEncountId = chargeWindow?.chargeVm?.settlementVm?.outChargeResponse?.outEncountId,
                };
                if (string.IsNullOrWhiteSpace(outRegisterResponse.outEncountId))
                {
                    outRegisterServer.PreRegistCancel(outPreRegisterResponse.preSettlementList.Select(s => s.outEncounterId).ToList());
                    return;
                }
                await this.dialogCoordinator.ShowMessageAsync(this, "成功" , $"挂号成功!");
                this.mainWindow?.Close();
            }
            catch (Exception ex)
            {
                await this.dialogCoordinator.ShowMessageAsync(this, "警告", $"结算失败!,{ex.Message}");
                outRegisterServer.PreRegistCancel(outPreRegisterResponse.preSettlementList.Select(s => s.outEncounterId).ToList());
            }
        });

        ///// <summary>
        ///// 取消事件
        ///// </summary>
        public ICommand cancel => new RelayCommand((object param) =>
        {
            if (this.outPreRegisterResponse != null)
            {
                outRegisterServer.PreRegistCancel(outPreRegisterResponse.preSettlementList.Select(s => s.outEncounterId).ToList());
            }
            try
            {
                mainWindow.Close();
            }
            catch (Exception)
            {
            }
            throw new SpeedException("HISBIZ", "用户取消了操作!");
        });
    }
}
